package com.cxyd.modules.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cxyd.common.page.PageData;
import com.cxyd.common.utils.Result;
import com.cxyd.common.constant.Constant;
import com.cxyd.common.exception.RootException;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.common.utils.ConvertUtils;
import com.cxyd.modules.core.service.SerialNumberService;
import com.cxyd.modules.sys.dto.SysUserDTO;
import com.cxyd.modules.sys.service.SysUserService;
import com.cxyd.modules.wms.dao.OrderDao;
import com.cxyd.modules.wms.dto.InterfaceMesDetailsDTO;
import com.cxyd.modules.wms.dto.OrderDTO;
import com.cxyd.modules.wms.entity.OrderDetailEntity;
import com.cxyd.modules.wms.entity.OrderEntity;
import com.cxyd.modules.wms.service.OrderDetailService;
import com.cxyd.modules.wms.service.OrderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;
import java.util.Map;

/**
 * 出库主单
 *
 * @author g_Cycle gengruyi01@163.com
 * @since 1.0.0 2023-04-27
 */
@Service
public class OrderServiceImpl extends CrudServiceImpl<OrderDao, OrderEntity, OrderDTO> implements OrderService {
    private final OrderDetailService detailService;
    private final SysUserService userService;
    private final SerialNumberService serialNumberService;

    public OrderServiceImpl(OrderDetailService detailService, SysUserService userService, SerialNumberService serialNumberService) {
        this.detailService = detailService;
        this.userService = userService;
        this.serialNumberService = serialNumberService;
    }

    @Override
    public PageData<OrderDTO> page(Map<String, Object> params) {
        //1.查询主单信息
        final IPage<OrderEntity> page = baseDao.selectPage(
                getPage(params, "", false),
                getWrapper(params)
        );
        //2.获取用户信息
        final List<SysUserDTO> userList = userService.getList();
        //3.将creator与updater的username通过id进行绑定
        page.getRecords().forEach(entity -> {
            if (entity.getCreator() != null) {
                entity.setCreatorName(userService.getUsernameById(entity.getCreator(), userList));
            }
            if (entity.getUpdater() != null) {
                entity.setUpdaterName(userService.getUsernameById(entity.getUpdater(), userList));
            }
        });
        return getPageData(page, OrderDTO.class);
    }

    @Override
    public QueryWrapper<OrderEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("orderId");
        String orderNo = (String) params.get("orderNo");
        String zllbh = (String) params.get("zllbh");
        String orderSt = (String) params.get("orderSt");


        QueryWrapper<OrderEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "ORDER_ID", id);
        wrapper.eq(StringUtils.isNotBlank(orderNo), "ORDER_NO", orderNo);
        wrapper.eq(StringUtils.isNotBlank(orderSt), "ORDER_ST", orderSt);
        wrapper.like(StringUtils.isNotBlank(zllbh), "zllbh", zllbh);
        //新增排序
        wrapper.orderBy(true, true, "(CASE order_st " +
                "WHEN 0 THEN 0 " +
                "WHEN 1 THEN 1 " +
                "WHEN 2 THEN 2 " +
                "WHEN 9 THEN 3 " +
                "ELSE 4 END)");
        wrapper.orderBy(true, true, "create_date");
        return wrapper;
    }

    @Override
    public void save(OrderDTO dto) {
        //1.获取订单编号
        String orderNo = serialNumberService.getSerialNumberByCode("order");
        //2.将dto转换为单据实体类
        final OrderEntity entity = ConvertUtils.sourceToTarget(dto, OrderEntity.class);
        //3.单据编号填充至实体类
        entity.setOrderNo(orderNo);
        //4.将数据写入数据库
        insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(@RequestBody Long[] ids) {
        for (int i = 0; i < ids.length; i++) {
            deleteOrderById(ids[i]);
        }
    }

    public void deleteOrderById(Long id) {
        OrderEntity entity = baseDao.selectById(id);
        //判断明细状态是否为初始状态
        if (entity.getOrderSt() != 0) {
            throw new RootException("只有初始状态主单才可以删除");
        }
        //删除
        baseDao.deleteById(id);
    }

    @Override
    public String getOrderStById(Long id) {

        if (id == null || id.longValue() == 0) {
            return "unknown";
        }
        OrderEntity entity = baseDao.selectById(id);

        return entity.getOrderSt().toString();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result importOrder(String zllbh, List<InterfaceMesDetailsDTO> details) {
        if (StringUtils.isBlank(zllbh)) {
            return new Result().error("领料单号不能为空");
        }
        if (details == null) {
            return new Result().error("领料信息不能为空");
        }
        List<OrderDetailEntity> entities = ConvertUtils.sourceToTarget(details, OrderDetailEntity.class);
        int rows = orderInsert(zllbh, entities);
        if (rows > 0) {
            return new Result().ok("");
        }
        return new Result().error("领料单写入WMS系统失败!");
    }

    public int orderInsert(String zllbh, List<OrderDetailEntity> entities) {
        //生成出库主单
        String orderNo = serialNumberService.getSerialNumberByCode("order");
        OrderEntity order = new OrderEntity();
        order.setOrderNo(orderNo);
        order.setBelongSystem(Constant.ClientCode.MES.getCode());
        order.setOrderType("MES_REQ_OT");
        order.setCreator(Constant.ClientCode.MES.getId());
        order.setUpdater(Constant.ClientCode.MES.getId());
        insert(order);
        //生成出库明细
        entities.stream().forEach(item -> {
            item.setOrderId(order.getOrderId());
            item.setZllbh(zllbh);
            item.setCreator(Constant.ClientCode.MES.getId());
            item.setUpdater(Constant.ClientCode.MES.getId());
        });
        return detailService.batchSave(entities);
    }
}